#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <tests_lib.h>

void __assert_func_failed(const char *file, int line, const char *func, const char *failedexpr)
{
    __test_all_asserts++;
    __test_failed_asserts++;
    if (__test_all_asserts > 1) {
        INFO("|--\033[31mAssertion \"%s\" false \033[0m\n", failedexpr);
        INFO("|    |--\033[31mFile: %s, Line: %d \033[0m\n", file, line);
        INFO("|    |__\033[31mFunction: %s \033[0m\n", func);
    } else {
        INFO("|--\033[31mAssertion \"%s\" false \033[0m\n", failedexpr);
        INFO("     |--\033[31mFile: %s, Line: %d \033[0m\n", file, line);
        INFO("     |--\033[31mFunction: %s \033[0m\n", func);
    }
}

void __assert_func_success(const char *file, int line, const char *func, const char *failedexpr)
{
    __test_all_asserts++;
    if (__test_all_asserts > 1) {
        INFO("|--\033[32mAssertion \"%s\" true \033[0m\n", failedexpr);
    } else {
        INFO("|--\033[32mAssertion \"%s\" true \033[0m\n", failedexpr);
    }
}

#define TEST_CASE_DESCS_NUM ((test_case_descs_end - test_case_descs_start)\
                            / sizeof(test_case_desc_t))

/*******************************************************************************
 * Simple routine to sanity check a test case descriptor before using it
 ******************************************************************************/
static int32_t validate_test_case_desc(const test_case_desc_t *desc)
{
    if (desc == NULL)
        return -EINVAL;

    /* A test having no init or exit function doesn't make sense */
    if (desc->run == NULL)
        return -EINVAL;

    return 0;
}

/*******************************************************************************
 * This function calls the initialisation routine in the descriptor declared by
 * a test case.
 ******************************************************************************/
void do_call_test_cases(void)
{
    int rc;
    uint8_t index;

    test_case_desc_t *test_case_descs;

    test_case_descs = (test_case_desc_t *)test_case_descs_start;
    for (index = 0; index < TEST_CASE_DESCS_NUM; index++) {
        test_case_desc_t *tcase = &test_case_descs[index];

        rc = validate_test_case_desc(tcase);
        if (rc != 0) {
            INFO("Invalid Testcase descriptor %p\n",
                    (void *) tcase);
            continue;
        }

        /* Call the initialisation routine for this test case */
        if (tcase->init != NULL)
            tcase->init();

        RUN_CASE(tcase->name, tcase->run);

        if (tcase->exit != NULL)
            tcase->exit();


    }
}

